package com.magnificent.panda.ui.dialog;

import com.silverhaze.commons.ui.dialogs.CommonDialog;
import com.silverhaze.commons.ui.dialogs.DialogConnector;
import com.silverhaze.commons.utils.collections.CollectionsUtils;
import com.silverhaze.commons.utils.collections.list.MetaList;
import com.silverhaze.commons.utils.collections.list.functions.PredicateFunction;
import com.magnificent.graph.model.Cell;
import com.silverhaze.commons.helpers.CommonUIHelper;
import com.magnificent.panda.model.entity.FlowEvent;
import com.magnificent.panda.resources.Resources;
import com.magnificent.panda.ui.dialog.panels.ValuePanel;
import com.magnificent.panda.utils.JFreeChartHelper;
import com.magnificent.panda.utils.PandaConstants;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * User: Babanin
 * Date: 06.03.2010
 * Time: 8:57:45
 */
public class ActorSettingsDialog extends CommonDialog {
    public static final int START_X = 36;
    public static final int END_X = 12;

    private JList settingsList;

    private JPanel flowSettingsPanel;
    private JPanel commonSettingsPanel;

    private JTabbedPane flowTabbedPane;
    private ChartPanel flowChartPanel;
    private ValuePanel flowValuesPanel;
    private JFreeChart chart;
    private MetaList<FlowEvent> flowValues;
    private JComboBox timeComboBox;
    private int currentTime;
    private JTextField actorNameTextField;

    private JButton clearButton;
    private JButton generateButton;
    private JButton undoLastActionButton;

    private Cell cell;

    public ActorSettingsDialog(Cell cell) {
        this.cell = cell;

        initializeControls();
        initializeView();
    }

    private void initializeControls() {
        flowValues = cell.getFlowActor().getEvents();

        int maxRangeValue = 50;
        if (flowValues.size() != 0) {
            maxRangeValue = (int) Math.max(flowValues.get(flowValues.size() - 1).getValue(), maxRangeValue);
        }

        chart = JFreeChartHelper.newFlowChart(JFreeChartHelper.createFlowDataset(flowValues), "", "", "", maxRangeValue);

        timeComboBox = new JComboBox(new Integer[]{
                10, 35, 40, 50, 60, 70, 80, 90, 100
        });

        flowChartPanel = new ChartPanel(chart);
        flowChartPanel.addChartMouseListener(new ChartMouseListener() {
            public void chartMouseClicked(ChartMouseEvent chartMouseEvent) {
                System.out.println(chartMouseEvent.getTrigger().getPoint());

                double current = chartMouseEvent.getTrigger().getX() - START_X;
                double max = flowChartPanel.getSize().getWidth() - START_X - END_X;

                int value = (int) Math.round(current / (max / currentTime));
                addFirstValue(value);
            }

            public void chartMouseMoved(ChartMouseEvent chartMouseEvent) {
            }
        });
        flowChartPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));

        generateButton = new JButton(new AbstractAction("Генерировать") {
            public void actionPerformed(ActionEvent e) {
                JPopupMenu popupMenu = new JPopupMenu();

                popupMenu.add(new JMenuItem(new AbstractAction("Добавить") {
                    public void actionPerformed(ActionEvent e) {
                        FlowGeneratorDialog flowGeneratorDialog = new FlowGeneratorDialog(new DialogConnector<int[]>() {
                            public void objectSelected(int[] obj) {
                                for (double anObj : obj) {
                                    flowValues.add(new FlowEvent(0, (long) anObj));
                                }

                                repaintFirstFlowChart();
                            }
                        }, true);
                        flowGeneratorDialog.setVisible(true);
                    }
                }));

                popupMenu.add(new JMenuItem(new AbstractAction("Заменить") {
                    public void actionPerformed(ActionEvent e) {
                        FlowGeneratorDialog flowGeneratorDialog = new FlowGeneratorDialog(new DialogConnector<int[]>() {
                            public void objectSelected(int[] obj) {
                                flowValues.clear();

                                for (double anObj : obj) {
                                    flowValues.add(new FlowEvent(0, (long) anObj));
                                }

                                repaintFirstFlowChart();
                            }
                        }, false);
                        flowGeneratorDialog.setVisible(true);
                    }
                }));

                popupMenu.show(generateButton, 0, generateButton.getHeight() + 2);
            }
        });

        clearButton = new JButton(new AbstractAction("Очистить") {
            public void actionPerformed(ActionEvent e) {
                flowValues.clear();
                repaintFirstFlowChart();
            }
        });

        undoLastActionButton = new JButton(new AbstractAction("Отменить действие") {
            public void actionPerformed(ActionEvent e) {
                if (flowValues.size() > 0) {
                    flowValues.remove(flowValues.size() - 1);
                    repaintFirstFlowChart();
                }
            }
        });

        flowValuesPanel = new ValuePanel(this, flowValues);

        flowTabbedPane = new JTabbedPane();
        flowTabbedPane.addTab("График", flowChartPanel);
        flowTabbedPane.addTab("Значения", flowValuesPanel);

        timeComboBox.setSelectedItem(50);
        timeComboBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                currentTime = Integer.parseInt(timeComboBox.getSelectedItem().toString());

                flowValuesPanel.updateMaxValue(currentTime);

                chart.getXYPlot().getDomainAxis(0).setRange(0, currentTime);

                flowValues = flowValues.where(new PredicateFunction<FlowEvent>() {
                    public boolean predicate(FlowEvent val) {
                        return val.getValue() <= currentTime;
                    }
                });

                repaintFirstFlowChart();
            }
        });

        flowSettingsPanel = new JPanel(new BorderLayout());
        commonSettingsPanel = new JPanel(new BorderLayout());

        actorNameTextField = new JTextField(cell.getValue().toString());

        currentTime = 50;
    }

    private void initializeView() {
        setIconImage(Resources.APP_ICON.getImage());
        setTitle(PandaConstants.PANDA_TITLE + " - Параметры пользователя '" + cell.getValue().toString() + "'");
        getRootPane().setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        flowSettingsPanel.add(CommonUIHelper.packInTitledPanel(
                CommonUIHelper.createBorderLayoutPanel(
                        CollectionsUtils.array(
                                CommonUIHelper.packInShiftedPanel(
                                        CommonUIHelper.createBorderLayoutPanel(
                                                CollectionsUtils.array(
                                                        CommonUIHelper.hBox(
                                                                generateButton, 20, undoLastActionButton, 5, clearButton
                                                        ), new JPanel()),
                                                CollectionsUtils.array(
                                                        BorderLayout.LINE_END,
                                                        BorderLayout.LINE_START
                                                )
                                        ), 5, 0, 0, 0
                                ),
                                flowTabbedPane),
                        CollectionsUtils.array(
                                BorderLayout.NORTH,
                                BorderLayout.CENTER
                        )
                ), BorderLayout.CENTER, "События"), BorderLayout.CENTER);


        commonSettingsPanel.add(
                CommonUIHelper.packInTitledPanel(
                        CommonUIHelper.createGridPanel(5, 5, 5, 5, 1, 2,
                                "Имя: ", actorNameTextField
                        ), BorderLayout.NORTH, "Общие"
                ), BorderLayout.CENTER);

        settingsList = new JList(new Object[]{
                "Общие",
                "События"
        });

        settingsList.setSelectedIndex(1);
        settingsList.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        settingsList.setPreferredSize(new Dimension(200, 500));

        settingsList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                ActorSettingsDialog.this.remove(flowSettingsPanel);
                ActorSettingsDialog.this.remove(commonSettingsPanel);

                int selectedIndex = settingsList.getSelectedIndex();

                switch (selectedIndex) {
                    case 0:
                        ActorSettingsDialog.this.add(commonSettingsPanel, BorderLayout.CENTER);
                        break;
                    case 1:
                        ActorSettingsDialog.this.add(flowSettingsPanel, BorderLayout.CENTER);
                        break;
                    default:
                        System.err.println("No setting panel with index = " + selectedIndex);
                }

                ActorSettingsDialog.this.repaint();
                ActorSettingsDialog.this.validate();
            }
        });

        add(CommonUIHelper.packInTitledPanel(settingsList, BorderLayout.CENTER, "Настройки"), BorderLayout.WEST);
        add(flowSettingsPanel, BorderLayout.CENTER);
        add(CommonUIHelper.packInPanel(CommonUIHelper.hBox(
                new JButton(new AbstractAction("Сохранить") {
                    public void actionPerformed(ActionEvent e) {
                        // Flow settings
                        cell.getFlowActor().setEvents(flowValues);

                        // Common settings
                        cell.setValue(actorNameTextField.getText().trim());

                        ActorSettingsDialog.this.dispose();
                    }
                }), 5,
                new JButton(new AbstractAction("Отмена") {
                    public void actionPerformed(ActionEvent e) {
                        ActorSettingsDialog.this.dispose();
                    }
                })
        ), BorderLayout.LINE_END), BorderLayout.SOUTH);

        setModal(true);
        pack();
        setLocationRelativeTo(null);
    }

    @Override
    public void cancelPressed() {
    }

    @Override
    public void okPressed() {
    }

    public void addFirstValue(long value) {
        if (!flowValues.contains(value)) {
            flowValues.add(new FlowEvent(-1, value));
            repaintFirstFlowChart();
        }
    }

    public void removeFirstValue(long value) {
        flowValues.remove((Object) value);

        repaintFirstFlowChart();
    }

    private void repaintFirstFlowChart() {
        flowValuesPanel.updateValues(flowValues);
        chart.getXYPlot().setDataset(JFreeChartHelper.createFlowDataset(flowValues));
    }

    public static void show(Cell cell) {
        ActorSettingsDialog dialog = new ActorSettingsDialog(cell);
        dialog.setVisible(true);
    }
}

  /* converted to utf8 */